package cn.com.scooper.impl.ks;

import cn.com.scooper.common.constant.CommonConstant;
import cn.com.scooper.common.util.StringUtils;
import cn.com.scooper.dao.xf.MineIotDeviceDao;
import cn.com.scooper.pojo.dto.ks.ReportActualDataDto;
import cn.com.scooper.pojo.dto.ks.ReportAlarmDataDto;
import cn.com.scooper.pojo.dto.ks.ReportRequestPkgDto;
import cn.com.scooper.pojo.po.MineIotDevicePo;
import cn.com.scooper.service.ks.KSReportDataService;
import cn.com.scooper.utils.AES128CBCwithPKCS5Utils;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.UUID;

@Service
@Slf4j
public class KSReportDataServiceImpl implements KSReportDataService {

    @Autowired
    private KSReportDataHandler ksReportDataHandler;

    @Autowired
    private MineIotDeviceDao mineIotDeviceDao;

    @Autowired
    private PropertyReader propertyReader;

    /**
     * 矿山实时数据接收
     * @param reportActualDataDto
     * @param enterpriseName
     * @return
     */
    @Override
    public int recvActualData(ReportActualDataDto reportActualDataDto, String enterpriseName) {
        try{
            log.info("【企业实时数据接收】上报企业：{}，数据内容：{}",enterpriseName,JSONObject.toJSONString(reportActualDataDto));
            ReportRequestPkgDto reportRequestPkgDto = createReportPackage(reportActualDataDto,null,CommonConstant.ReportDataType.KS_REPORT_ACTUAL_DATA,enterpriseName);
            if( reportRequestPkgDto == null ){
                return -1;
            }
            log.info("【企业实时数据接收】上报企业：{}，数据内容转换为市局上报报文：{}",enterpriseName,JSONObject.toJSONString(reportRequestPkgDto));
            boolean result = ksReportDataHandler.offer(reportRequestPkgDto,enterpriseName);
            log.info("【企业实时数据接收】上报企业：{}，市局上报报文存入内存结果：{}",enterpriseName,result);
            if( !result ){
                return -2;
            }
        }catch (Exception e){
            log.error("【企业实时数据接收】上报企业：{}，构造并存储市局上报报文失败：{}",enterpriseName,e.getMessage());
            return -1;
        }
        return 0;
    }

    /**
     * 矿山告警数据接收
     * @param reportAlarmDataDto
     * @param enterpriseName
     * @return
     */
    @Override
    public int recvAlarmData(ReportAlarmDataDto reportAlarmDataDto, String enterpriseName) {
       try{
           log.info("【企业告警数据接收】上报企业：{}，数据内容：{}",enterpriseName,JSONObject.toJSONString(reportAlarmDataDto));
           ReportRequestPkgDto reportRequestPkgDto = createReportPackage(null,reportAlarmDataDto,CommonConstant.ReportDataType.KS_REPORT_ALARM_DATA,enterpriseName);
           if( reportRequestPkgDto == null ){
               return -1;
           }
           log.info("【企业告警数据接收】上报企业：{}，数据内容转换为市局上报报文：{}",enterpriseName,JSONObject.toJSONString(reportRequestPkgDto));
           boolean result = ksReportDataHandler.offer(reportRequestPkgDto,enterpriseName);
           log.info("【企业告警数据接收】上报企业：{}，市局上报报文存入内存结果：{}",enterpriseName,result);
           if( !result ){
               return -2;
           }
        }catch (Exception e){
           log.error("【企业告警数据接收】上报企业：{}，构造并存储市局上报报文失败：{}",enterpriseName,e.getMessage());
           return -1;
        }
        return 0;
    }

    /**
     * 构造上报报文
     * @param reportActualDataDto
     * @param reportAlarmDataDto
     * @param reportDataType
     * @param enterpriseName
     * @return
     */
    public ReportRequestPkgDto createReportPackage(ReportActualDataDto reportActualDataDto, ReportAlarmDataDto reportAlarmDataDto,
                                                   String reportDataType, String enterpriseName){
        ReportRequestPkgDto reportRequestPkgDto = new ReportRequestPkgDto();

        String dataId = UUID.randomUUID().toString().replace("-","");

        String appId = null;
        String gatewayId = null;
        String enterpriseId = null;
        String sKey = null;
        String iv = null;

        switch (enterpriseName){
            case CommonConstant.ReportEnterpriseName.KS_ENTERPRISE_NFSN:
                appId = propertyReader.getAppIdNFSN();
                gatewayId = propertyReader.getGatewayIdNFSN();
                enterpriseId = propertyReader.getEnterpriseIdNFSN();
                sKey = propertyReader.getsKeyNFSN();
                iv = propertyReader.getIvNFSN();
                break;
            case CommonConstant.ReportEnterpriseName.KS_ENTERPRISE_HSSN:
                appId = propertyReader.getAppIdHSSN();
                gatewayId = propertyReader.getGatewayIdHSSN();
                enterpriseId = propertyReader.getEnterpriseIdHSSN();
                sKey = propertyReader.getsKeyHSSN();
                iv = propertyReader.getIvHSSN();
                break;
            case CommonConstant.ReportEnterpriseName.KS_ENTERPRISE_CYKY:
                appId = propertyReader.getAppIdCYKY();
                gatewayId = propertyReader.getGatewayIdCYKY();
                enterpriseId = propertyReader.getEnterpriseIdCYKY();
                sKey = propertyReader.getsKeyCYKY();
                iv = propertyReader.getIvCYKY();
                break;
            default:
                break;
        }

        String encrypt = null;
        String serviceId = null;
        String quotaId;
        switch (reportDataType){
            case CommonConstant.ReportDataType.KS_REPORT_ACTUAL_DATA:
                reportActualDataDto.setDataId(dataId);
                reportActualDataDto.setEnterpriseId(enterpriseId);
                reportActualDataDto.setGatewayId(gatewayId);
                for (ReportActualDataDto.DataPo dataPo : reportActualDataDto.getDatas()) {
                    quotaId = transQuotaId(dataPo.getQuotaId());
                    if( StringUtils.isEmpty(quotaId) ){
                        return null;
                    }
                    dataPo.setQuotaId(quotaId);
                    for (ReportActualDataDto.DataValuePo dataValuePo : dataPo.getValues()) {
                        dataValuePo.setChildParam(transChildParam(dataValuePo.getChildParam()));
                    }
                }
                log.info("【企业实时数据接收】上报企业：{}，数据内容转换为市局上报报文data：{}",enterpriseName,JSONObject.toJSONString(reportActualDataDto));
                encrypt = AES128CBCwithPKCS5Utils.encrypt(JSONObject.toJSONString(reportActualDataDto),sKey,iv);
                serviceId = CommonConstant.ReportServiceId.KS_REPORT_ACTUAL_DATA;
                break;
            case CommonConstant.ReportDataType.KS_REPORT_ALARM_DATA:
                reportAlarmDataDto.setDataId(dataId);
                reportAlarmDataDto.setEnterpriseId(enterpriseId);
                reportAlarmDataDto.setGatewayId(gatewayId);
                for (ReportAlarmDataDto.AlarmPo alarmPo : reportAlarmDataDto.getAlarms()) {
                    quotaId = transQuotaId(alarmPo.getQuotaId());
                    if( StringUtils.isEmpty(quotaId) ){
                        return null;
                    }
                    alarmPo.setQuotaId(quotaId);
                    for (ReportAlarmDataDto.AlarmValuePo alarmValuePo : alarmPo.getValues()) {
                        alarmValuePo.setChildParam(transChildParam(alarmValuePo.getChildParam()));
                    }
                }
                log.info("【企业告警数据接收】上报企业：{}，数据内容转换为市局上报报文data：{}",enterpriseName,JSONObject.toJSONString(reportAlarmDataDto));
                encrypt = AES128CBCwithPKCS5Utils.encrypt(JSONObject.toJSONString(reportAlarmDataDto),sKey,iv);
                serviceId = CommonConstant.ReportServiceId.KS_REPORT_ALARM_DATA;
                break;
            default:
                break;
        }

        reportRequestPkgDto.setAppId(appId);
        reportRequestPkgDto.setServiceId(serviceId);
        reportRequestPkgDto.setDataId(dataId);
        reportRequestPkgDto.setData(encrypt);
        reportRequestPkgDto.setDataType(reportDataType);

        return reportRequestPkgDto;
    }

    /**
     * 企业->市局设备编码转换
     *
     * @param quotaId
     * @return
     */
    private String transQuotaId(String quotaId) {
        MineIotDevicePo mineIotSlopeDeviceQo = new MineIotDevicePo();
        mineIotSlopeDeviceQo.setSourceId(quotaId);
        List<MineIotDevicePo> list = mineIotDeviceDao.selectAll(mineIotSlopeDeviceQo);
        if( list.isEmpty() ){
            log.info("【向市局上报数据->查找企业设备与市局设备对应关系】企业设备id：{}未找到对应市局设备id",quotaId);
            return null;
        }
        log.info("【向市局上报数据->查找企业设备与市局设备对应关系】企业设备id：{}找到对应市局设备id：{}",quotaId,list.get(0).getQuotaId());
        return list.get(0).getQuotaId();
    }


    /**
     * 企业->市局子参数类型转换
     *
     * @param param
     * @return
     */
    private String transChildParam(String param) {
        String childParam = "";
        switch (param.toUpperCase()){
            case "X":
                childParam = CommonConstant.ReportEquipType.SURFACE_DIS_DEV.getChildParamX();
                break;
            case "Y":
                childParam = CommonConstant.ReportEquipType.SURFACE_DIS_DEV.getChildParamY();
                break;
            case "Z":
                childParam = CommonConstant.ReportEquipType.SURFACE_DIS_DEV.getChildParamZ();
                break;
            default:
                break;
        }
        return childParam;
    }
}
